package com.mmall.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.mmall.common.dtree.CheckArr;
import com.mmall.common.dtree.DTree;
import com.mmall.dao.SysAclMapper;
import com.mmall.dao.SysAclModuleMapper;
import com.mmall.dto.AclDto;
import com.mmall.dto.AclModuleLevelDto;
import com.mmall.dto.DeptUserDto;
import com.mmall.model.SysDept;
import com.mmall.model.SysRole;
import com.mmall.model.SysUser;
import com.mmall.util.LevelUtil;

@Service
public class SysTreeService {

    @Resource
    private SysDeptService sysDeptService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysAclModuleMapper sysAclModuleMapper;
    @Resource
    private SysCoreService sysCoreService;
    @Resource
    private SysAclMapper sysAclMapper;

    public List<DTree> deptTree() {
        List<SysDept> deptList = sysDeptService.getAllDept();
        return deptListToTree(deptList);
    }

    public List<DTree> deptListToTree(List<SysDept> deptLevelList) {
        if (CollectionUtils.isEmpty(deptLevelList)) {
            return Lists.newArrayList();
        }
        // level -> [dept1, dept2, ...] Map<String, List<Object>>
        Multimap<String, DTree> levelDeptMap = ArrayListMultimap.create();
        //List<DeptLevelDto> rootList = Lists.newArrayList();
        List<DTree> dtrees = new ArrayList<DTree>();
        DTree d = null;
        for (SysDept dto : deptLevelList) {
        	d = deptConvertDtree(dto);
        	levelDeptMap.put(dto.getLevel(), d);
            if (LevelUtil.ROOT.equals(dto.getLevel())) {
            	dtrees.add(d);
            }
        }
        // 按照seq从小到大排序
        Collections.sort(deptLevelList, new Comparator<SysDept>() {
            public int compare(SysDept o1, SysDept o2) {
                return Integer.parseInt(o1.getSeq()) - Integer.parseInt(o2.getSeq());
            }
        });
        // 递归生成树
        transformDeptTree(dtrees, LevelUtil.ROOT, levelDeptMap);
        return dtrees;
    }
    
    /**
     * 机构转tree方法
     * @param dept
     * @return
     */
    public DTree deptConvertDtree(SysDept dept){
    	DTree d = new DTree();
    	d.setId(dept.getId());
    	d.setTitle(dept.getName());
    	d.setLevel(dept.getLevel());
    	d.setParentId(dept.getParentId());
    	d.setSeq(dept.getSeq());
    	return d;
    }
    
    /**
     * 角色树
     * @return
     */
    public List<DTree> roleTree() {
        List<SysRole> roleList = sysRoleService.getAllRole();
        return roleListToTree(roleList);
    }

    public List<DTree> roleListToTree(List<SysRole> roleLevelList) {
        if (CollectionUtils.isEmpty(roleLevelList)) {
            return Lists.newArrayList();
        }
        // level -> [dept1, dept2, ...] Map<String, List<Object>>
        Multimap<String, DTree> levelRoleMap = ArrayListMultimap.create();
        //List<DeptLevelDto> rootList = Lists.newArrayList();
        List<DTree> dtrees = new ArrayList<DTree>();
        DTree d = null;
        for (SysRole dto : roleLevelList) {
        	d = roleConvertDtree(dto);
        	levelRoleMap.put(dto.getLevel(), d);
            if (LevelUtil.ROOT.equals(dto.getLevel())) {
            	dtrees.add(d);
            }
        }
        // 按照seq从小到大排序
        Collections.sort(roleLevelList, new Comparator<SysRole>() {
            public int compare(SysRole o1, SysRole o2) {
                return Integer.parseInt(o1.getSeq()) - Integer.parseInt(o2.getSeq());
            }
        });
        // 递归生成树
        transformDeptTree(dtrees, LevelUtil.ROOT, levelRoleMap);
        return dtrees;
    }
    
    /**
     * 角色转tree方法
     * @param dept
     * @return
     */
    public DTree roleConvertDtree(SysRole role){
    	DTree d = new DTree();
    	d.setId(role.getId());
    	d.setTitle(role.getName());
    	d.setLevel(role.getLevel());
    	d.setParentId(role.getParentId());
    	d.setSeq(role.getSeq());
    	return d;
    }
    
    /**
     * 用户拥有角色树结构
     * @return
     */
    public List<DTree> roleUserTree(String roled) {
    	Map<String, DeptUserDto> userDeptMap = sysRoleService.roleUserTree(roled);
        return roleUserListToTree(userDeptMap);
    }
    
    /**
     * 循环获取上级角色
     * @param roleListAll 用于接收返回结果的集合
     * @param sysRole 当前机构查询条件
     *//*
    public void getParentRole(List<SysRole> roleListAll,SysRole sysRole){
		SysRole resultSysRole =sysRoleService.selectByPrimaryKey(sysRole.getParentId());
		if(null != resultSysRole && !roleListAll.contains(resultSysRole)){
			roleListAll.add(resultSysRole);
			getParentRole(roleListAll,resultSysRole);
    	}
    }*/
    /**
     * 角色转tree方法
     * @param dept
     * @return
     */
    public DTree userConvertDtree(SysUser user,String parentId,String seq){
    	DTree d = new DTree();
    	d.setId(user.getId());
    	d.setTitle(user.getUserName());
    	d.setLevel("1");
    	d.setParentId(parentId);
    	d.setSeq(seq);
    	return d;
    }
    
    /**
     * 用户拥有角色树结构
     * @param roleLevelList
     * @return
     */
    public List<DTree> roleUserListToTree(Map<String, DeptUserDto> userDeptMap) {
        if (userDeptMap.isEmpty()) {
            return Lists.newArrayList();
        }
        List<DTree> dtrees = new ArrayList<DTree>();
        List<DTree> tempDeptList = null;
        List<SysDept> deptList = null;
        List<CheckArr> list = new ArrayList<CheckArr>();
        list.add(new CheckArr());
        
        for (Iterator<String> iterator = userDeptMap.keySet().iterator(); iterator.hasNext();) {
        	tempDeptList = new ArrayList<DTree>();
        	DTree d = null;
        	String deptId = iterator.next();
        	deptList = Lists.newArrayList();
        	SysDept sysDept = sysDeptService.getDeptById(deptId);
        	sysDeptService.getDeptLevelInfo(deptList,sysDept);
        	// 按照seq从小到大排序(由父类向子类排序)
        	Collections.sort(deptList, new Comparator<SysDept>() {
                public int compare(SysDept o1, SysDept o2) {
                	if(StringUtils.compare(o1.getLevel(), o2.getLevel()) > 0){
                		return 1;
                	}else if(StringUtils.compare(o1.getLevel(), o2.getLevel()) < 0){
                		return -1;
                	}else{
                		return 0;
                	}
                }
            });
        	String deptName = "";
        	for (SysDept sysDeptDto : deptList) {
        		deptName += sysDeptDto.getName() + "-->";
			}
        	sysDept.setName(deptName);
        	sysDept.setLevel(LevelUtil.ROOT);
        	DTree parentD = deptConvertDtree(sysDept);
        	dtrees.add(parentD);
        	
        	DeptUserDto deptUserDto = (DeptUserDto) userDeptMap.get(deptId);
        	for (int i = 0; i < deptUserDto.getUserList().size(); i++) {
        		d = userConvertDtree(deptUserDto.getUserList().get(i),deptId,String.valueOf(i));
        		d.setCheckArr(list);
        		tempDeptList.add(d);
			}
        	parentD.setCheckArr(list);
        	parentD.setChildren(tempDeptList);
		}
        // 递归生成树
        //transformDeptTree(dtrees, LevelUtil.ROOT, levelRoleMap);
        return dtrees;
    }
    
    public void transformDeptTree(List<DTree> dtrees, String level, Multimap<String, DTree> levelDeptMap) {
    	List<CheckArr> list = new ArrayList<CheckArr>();
        list.add(new CheckArr());
        for (int i = 0; i < dtrees.size(); i++) {
            // 遍历该层的每个元素
        	DTree dTree = dtrees.get(i);
        	//给每层添加复选框
        	dTree.setCheckArr(list);
            // 处理当前层级的数据
            String nextLevel = LevelUtil.calculateLevel(level, dTree.getId());
            // 处理下一层
            List<DTree> tempDeptList = (List<DTree>) levelDeptMap.get(nextLevel);
            if (CollectionUtils.isNotEmpty(tempDeptList)) {
                // 排序
                Collections.sort(tempDeptList, deptSeqComparator);
                // 设置下一层部门
                dTree.setChildren(tempDeptList);
                // 进入到下一层处理
                transformDeptTree(tempDeptList, nextLevel, levelDeptMap);
            }
        }
    }

    public Comparator<DTree> deptSeqComparator = new Comparator<DTree>() {
        public int compare(DTree o1, DTree o2) {
            return Integer.parseInt(o1.getSeq()) - Integer.parseInt(o2.getSeq());
        }
    };

    public Comparator<AclModuleLevelDto> aclModuleSeqComparator = new Comparator<AclModuleLevelDto>() {
        public int compare(AclModuleLevelDto o1, AclModuleLevelDto o2) {
            return Integer.parseInt(o1.getSeq()) - Integer.parseInt(o2.getSeq());
        }
    };

    public Comparator<AclDto> aclSeqComparator = new Comparator<AclDto>() {
        public int compare(AclDto o1, AclDto o2) {
            return Integer.parseInt(o1.getSeq()) - Integer.parseInt(o2.getSeq());
        }
    };
}
